(*
This file is part of the Lustre reader

* Copyright (c) 2010, Nicola Camuffo.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of Nicola Camuffo, nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*)


open Lustypes


(* implements a simple counter with 'next' method that increments the internal value *)
class counter :
  object
    method next : int
    method set : int -> unit
    method value : int
  end


(* simple stack that permit to get nth element *)
class ['a] stack :
  object
    method push : 'a -> unit
    method pop : unit -> unit
    method top : unit -> 'a
(*
    method scan_down : unit -> 'a
    method up : unit -> unit
*)
    method get : int -> 'a
end

(* like 'List.map2' but with 3 lists in input *)
val map3 : ('a -> 'b -> 'c -> 'd) -> 'a list -> 'b list -> 'c list -> 'd list

(* like 'List.iter2' but with 3 lists in input *)
val iter3 : ('a -> 'b -> 'c -> unit) -> 'a list -> 'b list -> 'c list -> unit

(* like 'List.split' but split the list in 3 parts *)
val split3 : ('a * 'b * 'c) list -> 'a list * 'b list * 'c list

(* see 'split3' *)
val split4 : ('a * 'b * 'c * 'd) list -> 'a list * 'b list * 'c list * 'd list

(* like 'List.combine' but with 3 lists in input *)
val combine3 : 'a list -> 'b list -> 'c list -> ('a * 'b * 'c) list


(* returns a slice of list, from n1 to n2 index, with step s *)
val slice_step : 'a list -> int -> int -> int -> 'a list

(* 'slice_step' with unary step *)
val slice : 'a list -> int -> int -> 'a list


(* returns the list obtained removing the second one from the first one *)
val difference : 'a list -> 'a list -> 'a list

(* returns position of the first element that verify the predicate *)
val position : ('a -> bool) -> 'a list -> int


(* creates a list of elements given length and element *)
val init_list : 'a -> int -> 'a list


	
(* if data is not stored, raises exception with message *)
val safe_find : ('a,'b)Hashtbl.t -> 'a -> string -> 'b

(* save unique value; raises exception with message if data is already stored *)
val safe_set : ('a,'b)Hashtbl.t -> 'a -> 'b -> string -> unit

(* save value in list; raises exception with message if data is already in list *)
val safe_set_in_list : ('a,'b list)Hashtbl.t -> 'a -> 'b -> string -> unit
